﻿using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Geometry;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace CPPEI.Coolzon.UI.PetroleumDataPartLib
{
    public partial class GisMapPart
    {
        #region 属性
        [Category("Data")]
        [DisplayName("要定位的业务层Id")]
        [Description("LayerId")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "LayerId", "要定位的业务层Id")]
        public string XLayerId { get; set; }


        [Category("Data")]
        [DisplayName("设置图层可见性int数组")]
        [Description("VisibleLayers")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "VisibleLayers", "设置图层可见性int数组")]
        public string VisibleLayers
        {
            get
            {
                return (string)GetValue(VisibleLayersProperty);
            }
            set
            {
                SetValue(VisibleLayersProperty, value);
            }
        }

        [Category("Data")]
        [DisplayName("地图范围")]
        [Description("Extent")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "Extent", "地图范围")]
        public string XExtent
        {
            get
            {
                return (string)GetValue(ExtentProperty);
            }
            set
            {
                SetValue(ExtentProperty, value);
                if (!string.IsNullOrWhiteSpace(value))
                {
                    SetExtent(value);
                }
            }
        }

        [Category("Data")]
        [DisplayName("地图服务地址")]
        [Description("TileServices")]
        [Editor(typeof(XProperty.Editors.XTileServiceEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "TileServices", "地图服务地址")]
        public List<TileService> XTileServices
        {
            get
            {
                return (List<TileService>)GetValue(TileServicesProperty);
            }
            set
            {
                SetValue(TileServicesProperty, value);
            }
        }

        [Category("Data")]
        [DisplayName("基地址")]
        [Description("BaseUrl")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "BaseUrl", "基地址")]
        public string XBaseUrl
        {
            get
            {
                return (string)GetValue(BaseUrlProperty);
            }
            set
            {
                SetValue(BaseUrlProperty, value);
            }
        }

        [Category("Data")]
        [DisplayName("业务服务地址")]
        [Description("FeatureLayers")]
        [Editor(typeof(XProperty.Editors.XFeatureLayEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "FeatureLayers", "业务服务地址")]
        public List<FeatureLayer> XFeatureLayers
        {
            get
            {
                return (List<FeatureLayer>)GetValue(FeatureLayersProperty);
            }
            set
            {
                SetValue(FeatureLayersProperty, value);
            }
        }

        [Category("Data")]
        [DisplayName("缩放级别")]
        [Description("ZoomIn")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "ZoomIn", "缩放级别")]
        public double? XZoomIn
        {
            get
            {
                return (double?)GetValue(ZoomProperty);
            }
            set
            {
                if (XZoomIn == value)
                {
                    this.Zoom(XZoomIn.Value);
                }
                else
                {
                    SetValue(ZoomProperty, value);
                }

            }
        }

        [Category("Data")]
        [DisplayName("初始位置")]
        [Description("InitialLocation")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "InitialLocation", "初始位置")]
        public string XInitialLocation
        {
            get
            {
                return (string)GetValue(InitialLocationProperty);
            }
            set
            {
                SetValue(InitialLocationProperty, value);
            }
        }

        [Category("Data")]
        [DisplayName("是否允许交互")]
        [Description("IsEnableInteraction")]
        [Editor(typeof(UI.XProperty.Editors.XBooleanEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "IsEnableInteraction", "是否允许交互")]
        public bool XIsEnableInteraction { get; set; }

        [Category("Data")]
        [DisplayName("最小分辨率")]
        [Description("MinResolution")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "MinResolution", "最小分辨率")]
        public double? XMinResolution { get; set; }

        [Category("Data")]
        [DisplayName("定位坐标")]
        [Description("LocationPoint")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "LocationPoint", "定位坐标")]
        public string XLocationPoint
        {
            get { return (string)GetValue(LocationPointProperty); }
            set { SetValue(LocationPointProperty, value); }
        }
        [Category("Data")]
        [DisplayName("定位分辨率")]
        [Description("LocationResolution")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "LocationResolution", "定位分辨率")]
        public double? XLocationResolution
        {
            get { return (double?)GetValue(LocationResolutionProperty); }
            set { SetValue(LocationResolutionProperty, value); }
        }

        [Category("Data")]
        [DisplayName("地图级别")]
        [Description("MapLevel")]
        [Editor(typeof(UI.XProperty.Editors.XIntEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "MapLevel", "地图级别")]
        public int? XMapLevel
        {
            get { return (int?)GetValue(MapLevelProperty); }
            set
            {
                SetValue(MapLevelProperty, value);
                SetResolution(value.Value);
            }
        }
        [Category("Data")]
        [DisplayName("图层查询专用")]
        [Description("LayerIds")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "LayerIds", "图层查询专用")]
        public string XLayerIds
        {
            get { return (string)GetValue(LayerIdsProperty); }
            set { SetValue(LayerIdsProperty, value); }
        }
        [Category("Data")]
        [DisplayName("是否响应选中事件")]
        [Description("IsSelect")]
        [Editor(typeof(UI.XProperty.Editors.XBooleanEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "IsSelect", "是否响应选中事件")]
        public bool XIsSelect { get; set; }
        [Category("Data")]
        [DisplayName("选中后图形大小")]
        [Description("SelectSize")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "SelectSize", "选中后图形大小")]
        public double XSelectSize { get; set; }
        [Category("Data")]
        [DisplayName("选中后图形画刷")]
        [Description("SelectBrush")]
        [Editor(typeof(UI.XProperty.Editors.XBrushEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Data, "SelectBrush", "选中后图形画刷")]
        public BrushEx XSelectBrush { get; set; }
        #endregion

        #region DependencyPropery
        private static readonly DependencyProperty InitialLocationProperty =
           DependencyProperty.Register("InitialLocation", typeof(string), typeof(GisMapPart),
           new PropertyMetadata(new PropertyChangedCallback(InitialLocationPropertyChangedCallback)));

        private static readonly DependencyProperty ZoomProperty =
           DependencyProperty.Register("Zoom", typeof(double?), typeof(GisMapPart),
           new PropertyMetadata(new PropertyChangedCallback(ZoomPropertyChangedCallback)));

        private static readonly DependencyProperty ExtentProperty =
           DependencyProperty.Register("Extent ", typeof(string), typeof(GisMapPart));

        private static readonly DependencyProperty TileServicesProperty =
            DependencyProperty.Register("TileServices", typeof(List<TileService>), typeof(GisMapPart), new PropertyMetadata(TileServicesPropertyChangedCallback));

        private static readonly DependencyProperty BaseUrlProperty =
           DependencyProperty.Register("BaseUrl ", typeof(string), typeof(GisMapPart),
           new PropertyMetadata("http://gis.a4.petrochina/arcgis/rest/services/TJS/A4_SCJYZHZSPT/MapServer/", BaseUrlPropertyChangedCallback));

        private static readonly DependencyProperty FeatureLayersProperty =
                    DependencyProperty.Register("FeatureLayers", typeof(List<FeatureLayer>), typeof(GisMapPart), new PropertyMetadata(FeatureLayersPropertyChangedCallback));

        private static readonly DependencyProperty VisibleLayersProperty =
                    DependencyProperty.Register("VisibleLayers", typeof(string), typeof(GisMapPart));

        private static readonly DependencyProperty LocationResolutionProperty =
            DependencyProperty.Register("LocationResolution", typeof(double?), typeof(GisMapPart));



        private static readonly DependencyProperty LocationPointProperty =
            DependencyProperty.Register("LocationPoint", typeof(string), typeof(GisMapPart));

        private static readonly DependencyProperty MapLevelProperty =
            DependencyProperty.Register("MapLevel", typeof(int?), typeof(GisMapPart));

        private static readonly DependencyProperty LayerIdsProperty =
            DependencyProperty.Register("LayerIds", typeof(string), typeof(GisMapPart));

        #endregion
        private static void FeatureLayersPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                GisMapPart part = d as GisMapPart;
                part.ClearMapLayer(typeof(ESRI.ArcGIS.Client.FeatureLayer));
                List<FeatureLayer> featureLayers = e.NewValue as List<FeatureLayer>;

                GraphicsLayer graphicsLayers = part.map.Layers["myg"] as GraphicsLayer;
                if (graphicsLayers != null)
                {
                    graphicsLayers.ClearGraphics();
                }

                foreach (FeatureLayer flayer in featureLayers)
                {
                    ESRI.ArcGIS.Client.FeatureLayer layer = new ESRI.ArcGIS.Client.FeatureLayer() { ID = flayer.LayerId, Url = flayer.Url };
                    layer.DisableClientCaching = true;
                    layer.Mode = ESRI.ArcGIS.Client.FeatureLayer.QueryMode.OnDemand;
                    layer.InitializationFailed += part.layer_InitializationFailed;
                    layer.UpdateFailed += part.layer_UpdateFailed;
                    if (part.XLayerId == flayer.LayerId)
                    {
                        layer.UpdateCompleted += part.layer_UpdateCompleted;
                    }
                    part.map.Layers.Add(layer);
                    if (layer.ID == part.XLayerId)
                    {
                        ESRI.ArcGIS.Client.Symbols.SimpleMarkerSymbol sms = new ESRI.ArcGIS.Client.Symbols.SimpleMarkerSymbol();
                        sms.Color = new SolidColorBrush(Colors.Red);
                        sms.Size = 25;
                        sms.Style = ESRI.ArcGIS.Client.Symbols.SimpleMarkerSymbol.SimpleMarkerStyle.Circle;

                        SimpleRenderer sr = new SimpleRenderer();
                        sr.Symbol = sms;

                        layer.Renderer = sr;
                    }
                }

                part.SetVisibilityLayers();
            }
        }

        private static void TileServicesPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                GisMapPart part = d as GisMapPart;
                part.ClearMapLayer(typeof(OGCMapLayer));
                List<TileService> tileServices = e.NewValue as List<TileService>;
                foreach (TileService tile in tileServices)
                {
                    OGCMapLayer baseMap = new OGCMapLayer(tile.Url, tile.Type);
                    part.map.Layers.Add(baseMap);

                    baseMap.Initialized += part.baseMap_Initialized;
                    baseMap.TileLoaded += part.baseMap_TileLoaded;
                }
                //当XBaseUrl有默认值时，需要做如下处理
                part.AddBaseMap();
            }
        }

        private static void BaseUrlPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GisMapPart part = d as GisMapPart;
            if (e.NewValue != null)
            {
                part.ClearMapLayer(typeof(ArcGISDynamicMapServiceLayer));
                part.AddBaseMap();
            }
        }

        private static void InitialLocationPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                GisMapPart gmp = d as GisMapPart;
                gmp.PanTo(e.NewValue.ToString());
            }
        }

        private static void ZoomPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                GisMapPart gmp = d as GisMapPart;
                gmp.Zoom((double)e.NewValue);
            }
        }
    }
}
